﻿using System;

using Microsoft.Practices.Unity;

using Fuse8.DomainFramework.Common.Locator;

namespace Fuse8.DomainFramework.UnityLocator
{
    /// <summary>
    /// 
    /// </summary>
    internal class UnityServiceLocatorEx : UnityServiceLocator, IServiceLocatorEx
    {
        private IUnityContainer _innerContainer;
        private IUnityContainer _innerChildContainer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        public UnityServiceLocatorEx(IUnityContainer container)
            : base(container)
        {
            _innerContainer = container;
            _innerChildContainer = _innerContainer.CreateChildContainer();
        }

        #region IServiceLocatorEx Members

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="service"></param>
        public void Register<TService>(TService service)
        {
            _innerContainer.RegisterInstance<TService>(service);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="key"></param>
        /// <param name="service"></param>
        public void Register<TService>(string key, TService service)
        {
            _innerContainer.RegisterInstance<TService>(key, service);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="typeTo"></param>
        /// <param name="serviceType"></param>
        public void Register(Type typeTo, Type serviceType)
        {
            _innerContainer.RegisterType(typeTo, serviceType);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="typeTo"></param>
        /// <param name="serviceType"></param>
        /// <param name="key"></param>
        public void Register(Type typeTo, Type serviceType, string key)
        {
            _innerContainer.RegisterType(typeTo, serviceType, key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <returns></returns>
        public bool IsRegistered<TService>()
        {
            return _innerContainer.IsRegistered<TService>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsRegistered<TService>(string key)
        {
            return _innerContainer.IsRegistered<TService>(key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceType"></param>
        /// <returns></returns>
        public bool IsRegistered(Type serviceType)
        {
            return _innerContainer.IsRegistered(serviceType);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsRegistered(Type serviceType, string key)
        {
            return _innerContainer.IsRegistered(serviceType, key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="service"></param>
        public void SetDefaultService<TService>(TService service)
        {
            _innerChildContainer.RegisterInstance<TService>(service);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceType"></param>
        public void SetDefaultService(Type serviceType)
        {
            _innerChildContainer.RegisterType(serviceType);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <returns></returns>
        public TService GetDefaultService<TService>()
        {
            return _innerChildContainer.Resolve<TService>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceType"></param>
        /// <returns></returns>
        public object GetDefaultService(Type serviceType)
        {
            return _innerChildContainer.Resolve(serviceType);
        }

        /// <summary>
        /// Check if an instance of TService is registered in IoC as default service
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <returns>True if registered, false if not</returns>
        public bool IsDefaultServiceRegistered<TService>()
        {
            return _innerChildContainer.IsRegistered<TService>();
        }

        /// <summary>
        /// Check if a type is registered in IoC as a type for default service
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        /// <returns>True if registered, false if not</returns>
        public bool IsDefaultServiceRegistered(Type serviceType)
        {
            return _innerChildContainer.IsRegistered(serviceType);
        }

        #endregion
    }
}
